﻿using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using MesProjectWinform.Entity.Request;
using MesProjectWinform.Helper;
using MesProjectWinform.Public;
using MesProjectWinform.Public.Common;
using MesProjectWinform.WareHouse.Entity;
using MesProjectWinform.WareHouse.Form.仓库定义;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;

namespace MesProjectWinform.WareHouse.Form.外部标签解析
{
    public partial class Form_TagLableAdd : DevExpress.XtraEditors.XtraForm
    {
        public Form_TagLableAdd()
        {
            InitializeComponent();

            // 窗体显示后事件
            this.Shown += Form_TagLableAdd_Shown;
        }

        public bool UpdateType = false;

        // 使用LableModel类来接收数据
        public LableModel CurrentLabel { get; set; }

        private async void Form_TagLableAdd_Load(object sender, EventArgs e)
        {
            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;

                // 加载供应商下拉框数据
                await LoadSupplierComboBox();

                if (UpdateType)
                {
                    // 新增模式
                    this.Text = "新增标签解析";
                    btnAdd.Text = "新增";

                    // 直接异步获取编码并设置到文本框
                    string code = await GetCode();
                    txtLabelId.Text = code;

                    // 启用状态默认为是
                    toggleIsEnable.IsOn = true;
                }
                else
                {
                    // 修改模式
                    this.Text = "修改标签解析";
                    btnAdd.Text = "保存";

                    // 绑定传入的数据到控件
                    if (CurrentLabel != null)
                    {
                        // 填充表单控件
                        txtLabelId.Text = CurrentLabel.LalId;
                        txtLabelName.Text = CurrentLabel.LabName;
                        txtDelimiter.Text = CurrentLabel.Delimiter;
                        txtMemo.Text = CurrentLabel.Memo;
                        toggleIsEnable.IsOn = CurrentLabel.IsEnable;


                        // 设置规则
                        if (!string.IsNullOrEmpty(CurrentLabel.Format))
                        {
                            // 解析规则并设置
                            listTagID = ParseRulesText(CurrentLabel.Format);

                            UpdateRulesTextBox();
                        }
                    }
                }
                
                // 手动触发下拉框值改变事件，确保选中项显示正确
                //lookUpSupplier.RefreshEditValue();
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载窗体时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 窗体显示后事件 - 确保编码显示
        /// </summary>
        private async void Form_TagLableAdd_Shown(object sender, EventArgs e)
        {
            // 仅在新增模式且编码为空时重新获取
            if (UpdateType && string.IsNullOrEmpty(txtLabelId.Text))
            {
                try
                {
                    string code = await GetCode();
                    txtLabelId.Text = code;
                }
                catch (Exception ex)
                {
                    //System.Diagnostics.Debug.WriteLine($"窗体显示后获取编码异常: {ex.Message}");
                }
            }
        }


        #region 自定义方法

        /// <summary>
        /// 解析规则文本，格式为"(Id)name,(Id)name"
        /// </summary>
        /// <param name="rulesText">规则文本</param>
        /// <returns>解析后的规则字典，键为ID，值为名称</returns>
        private Dictionary<string, string> ParseRulesText(string rulesText)
        {
            Dictionary<string, string> rules = new Dictionary<string, string>();

            if (string.IsNullOrEmpty(rulesText))
                return rules;

            try
            {
                // 分割多个规则
                string[] ruleItems = rulesText.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string item in ruleItems)
                {
                    string trimmedItem = item.Trim();
                    if (string.IsNullOrEmpty(trimmedItem))
                        continue;

                    // 尝试提取ID和名称
                    string ruleId = string.Empty;
                    string ruleName = string.Empty;

                    // 检查是否包含括号格式 "(Id)Name"
                    int startBracket = trimmedItem.IndexOf('(');
                    int endBracket = trimmedItem.IndexOf(')');

                    if (startBracket >= 0 && endBracket > startBracket)
                    {
                        // 提取括号中的ID
                        ruleId = trimmedItem.Substring(startBracket + 1, endBracket - startBracket - 1).Trim();

                        // 如果括号后面有名称，提取名称
                        if (endBracket + 1 < trimmedItem.Length)
                        {
                            ruleName = trimmedItem.Substring(endBracket + 1).Trim();
                        }
                    }
                    else
                    {
                        // 检查是否包含空格（可能是"Id Name"格式）
                        int spaceIndex = trimmedItem.IndexOf(' ');

                        if (spaceIndex > 0)
                        {
                            // 假设空格前是ID，空格后是名称
                            ruleId = trimmedItem.Substring(0, spaceIndex).Trim();
                            ruleName = trimmedItem.Substring(spaceIndex + 1).Trim();
                        }
                        else
                        {
                            // 如果没有空格，假设整个字符串是ID
                            ruleId = trimmedItem;
                        }
                    }

                    // 添加到结果字典中
                    if (!string.IsNullOrEmpty(ruleId) && !rules.ContainsKey(ruleId))
                    {
                        rules.Add(ruleId, ruleName);
                    }
                }

                // 输出日志，方便调试
                if (rules.Count > 0)
                {
                    //System.Diagnostics.Debug.WriteLine($"解析到 {rules.Count} 个规则");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("解析规则信息时出错: " + ex.Message, "解析错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return rules;
        }

        /// <summary>
        /// 更新规则文本框，使用当前字典中的所有规则
        /// </summary>
        private void UpdateRulesTextBox()
        {
            try
            {
                if (listTagID == null || listTagID.Count == 0)
                {
                    txtRules.Text = string.Empty;
                    return;
                }

                // 构建规则显示文本
                StringBuilder sb = new StringBuilder();
                foreach (var rule in listTagID)
                {
                    if (sb.Length > 0)
                    {
                        sb.Append(",");
                    }
                    sb.Append($"{rule.Value}");
                }

                txtRules.Text = sb.ToString();
            }
            catch (Exception ex)
            {
                //System.Diagnostics.Debug.WriteLine($"更新规则文本框时出错: {ex.Message}");
            }
        }



        /// <summary>
        /// 加载供应商下拉框数据
        /// </summary>
        private async Task LoadSupplierComboBox()
        {
            try
            {
                string json = await HttpClientHelper.RequestUrl(RequestType.Get, "WareHouse/BasicInfo/GetSupplier", null);
                ApiResult<List<SupplierModel>> result = JsonConvert.DeserializeObject<ApiResult<List<SupplierModel>>>(json);

                if (result != null && result.Code == ApiEnums.Success && result.Data != null)
                {

                    lookUpSupplier.Properties.ValueMember = "SupplierId";
                    lookUpSupplier.Properties.DisplayMember = "SupplierName";
                    lookUpSupplier.Properties.DataSource = result.Data;
                    // 设置列显示
                    lookUpSupplier.Properties.Columns.Clear();
                    lookUpSupplier.Properties.Columns.Add(new LookUpColumnInfo("SupplierId", "供应商编码"));
                    lookUpSupplier.Properties.Columns.Add(new LookUpColumnInfo("SupplierName", "供应商名称"));
                    lookUpSupplier.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
                    // 如果是修改模式并且有传入供应商ID，则选择对应项
                    if (!UpdateType && CurrentLabel != null && !string.IsNullOrEmpty(CurrentLabel.SupplierId))
                    {
                        lookUpSupplier.EditValue = CurrentLabel.SupplierId;
                    }
                    //// 否则选择第一项
                    //else if (result.Data.Count > 0)
                    //{
                    //    lookUpSupplier.ItemIndex = 0;
                    //}
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载供应商数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

       
        /// <summary>
        /// 获取标签编码
        /// </summary>
        private async Task<string> GetCode()
        {
            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;

                string codePrefix = DataConverHelper.GetPrefix(CodeType.ExternalTag);

                // 首先尝试直接生成一个新编码作为备选
                string fallbackCode = DataConverHelper.GenerateCode(CodeType.ExternalTag);

                // 获取互联网时间
                //DateTime internetTime = await GetInternetTime();
                ////System.Diagnostics.Debug.WriteLine($"互联网时间: {internetTime}，本地时间: {DateTime.Now}");

                try
                {
                    // 调用API获取最新编码
                    string apiUrl = "WareHouse/BasicInfo/GetCode?Type=" + codePrefix;

                    string json = await HttpClientHelper.RequestUrl(RequestType.Get, apiUrl, null);

                    if (string.IsNullOrEmpty(json))
                    {
                        return fallbackCode;
                    }

                    ApiResult<TypeCodeModel> typeModel = JsonConvert.DeserializeObject<ApiResult<TypeCodeModel>>(json);

                    if (typeModel == null || typeModel.Data == null)
                    {
                        return fallbackCode;
                    }

                    string lastCode = typeModel.Data.Code;

                    if (string.IsNullOrEmpty(lastCode))
                    {
                        return fallbackCode;
                    }

                    // 获取数字部分（后五位或全部，如果不足五位）
                    string numberPart;
                    string prefixPart;

                    // 提取数字部分和前缀部分
                    if (lastCode.Length >= 5)
                    {
                        // 如果编码长度超过5位，提取最后5位作为数字部分，其余作为前缀
                        numberPart = lastCode.Substring(lastCode.Length - 5);
                        prefixPart = lastCode.Substring(0, lastCode.Length - 5);
                    }
                    else
                    {
                        // 如果编码长度不足5位，就用整个编码作为数字部分，前缀为空
                        numberPart = lastCode;
                        prefixPart = "";
                    }

                    // 尝试解析为数字并自增1
                    if (int.TryParse(numberPart, out int lastNumber))
                    {
                        // 使用互联网时间获取当前日期字符串
                        string currentDateStr = DateTime.Now.ToString("yyMMdd");
                        string dateInPrefix = "";

                        // 检查前缀中是否包含日期信息
                        if (prefixPart.Length >= 8 && prefixPart.StartsWith(codePrefix))
                        {
                            dateInPrefix = prefixPart.Substring(2, 6);
                        }

                        // 如果前缀中的日期与当前日期不同，或者前缀不合规范，则重置编号并使用新日期
                        if (string.IsNullOrEmpty(prefixPart) || !prefixPart.StartsWith(codePrefix) ||
                            (dateInPrefix != currentDateStr && !string.IsNullOrEmpty(dateInPrefix)))
                        {
                            // 新的一天，编号从1开始
                            prefixPart = codePrefix + currentDateStr;
                            lastNumber = 1; // 重置为1
                        }
                        else
                        {
                            // 同一天，编号递增
                            lastNumber++;
                        }

                        // 数字部分解析成功，确保是5位数（前面补0）
                        string fiveDigitNumber = lastNumber.ToString("D5");

                        // 组合新编码
                        string newCode = prefixPart + fiveDigitNumber;
                        return newCode;
                    }
                    else
                    {
                        return fallbackCode;
                    }
                }
                catch (Exception ex)
                {
                    //System.Diagnostics.Debug.WriteLine($"获取编码异常: {ex.Message}");
                    return fallbackCode;
                }
            }
            finally
            {
                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 检查标签编码是否可用
        /// </summary>
        private async Task<bool> CheckCodeAvailability(string code)
        {
            try
            {
                // 调用API检查编码是否可用
                string url = $"WareHouse/Labe/CheckLabelExists?labelId={Uri.EscapeDataString(code)}";
                string json = await HttpClientHelper.RequestUrl(RequestType.Get, url, null);
                ApiResult<bool> result = JsonConvert.DeserializeObject<ApiResult<bool>>(json);

                // 返回true表示编码可用，false表示编码已被占用
                return result.Code == ApiEnums.Success && !result.Data;
            }
            catch (Exception ex)
            {
                //System.Diagnostics.Debug.WriteLine($"检查编码可用性时发生异常: {ex.Message}");
                // 出现异常时，假定编码可用，让后续流程继续（后端会再次检查）
                return true;
            }
        }

        /// <summary>
        /// 检查必填字段
        /// </summary>
        private string Check()
        {
            List<string> emptyFields = new List<string>();

            // 检查标签编号
            if (string.IsNullOrWhiteSpace(txtLabelId.Text))
            {
                emptyFields.Add("标签编号");
            }

            // 检查标签名称
            if (string.IsNullOrWhiteSpace(txtLabelName.Text))
            {
                emptyFields.Add("标签名称");
            }

            // 检查供应商
            if (lookUpSupplier.EditValue == null || string.IsNullOrWhiteSpace(lookUpSupplier.EditValue.ToString()))
            {
                emptyFields.Add("供应商");
            }

            // 检查分隔符
            if (string.IsNullOrWhiteSpace(txtDelimiter.Text))
            {
                emptyFields.Add("分隔符");
            }

            // 如果有空字段，返回错误消息
            if (emptyFields.Count > 0)
            {
                return $"添加失败，以下字段不能为空：{string.Join("、", emptyFields)}";
            }

            // 所有字段都已填写
            return string.Empty;
        }

        /// <summary>
        /// 更新编码记录
        /// </summary>
        public async Task UpdateCode()
        {
            try
            {
                // 根据操作类型选择API
                string url = "WareHouse/BasicInfo/UpdateCode";
                TypeCodeModel model = new TypeCodeModel();
                model.Code = txtLabelId.Text;
                model.CodeType = DataConverHelper.GetPrefix(CodeType.ExternalTag);
                model.CodeTypeName = "标签解析";
                string postData = JsonConvert.SerializeObject(model);

                // 设置重试次数
                int maxRetries = 3;
                int retryCount = 0;
                bool success = false;

                while (!success && retryCount < maxRetries)
                {
                    try
                    {
                        string json = await HttpClientHelper.RequestUrl(RequestType.Put, url, postData);
                        ApiResult<int> baseModel = JsonConvert.DeserializeObject<ApiResult<int>>(json);

                        if (baseModel != null && baseModel.Code == ApiEnums.Success)
                        {
                            success = true;
                            return;
                        }

                        // 如果失败，尝试重试
                        retryCount++;
                        if (retryCount < maxRetries)
                        {
                            await Task.Delay(1000 * retryCount);
                        }
                    }
                    catch (Exception ex)
                    {
                        //System.Diagnostics.Debug.WriteLine($"更新编码记录时发生异常: {ex.Message}");
                        retryCount++;
                        if (retryCount < maxRetries)
                        {
                            await Task.Delay(1000 * retryCount);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //System.Diagnostics.Debug.WriteLine($"更新编码记录失败: {ex.Message}");
                // 这里选择不抛出异常，因为即使编码记录更新失败，主业务流程已经完成
            }
        }

        private Dictionary<string, string> listTagID = new Dictionary<string, string>();
        /// <summary>
        /// 处理从CheckTagForm接收到的数据
        /// </summary>
        /// <param name="TagData">数据字典</param>
        private void HandleTagDataReceived(List<KeyValuePair<string, string>> TagData, string Rules)
        {
            try
            {
                // 清空原有数据
                listTagID.Clear();

                // 复制收到的员工数据
                if (TagData != null && TagData.Count > 0)
                {
                    foreach (var item in TagData)
                    {
                        listTagID[item.Key] = item.Value;
                    }

                    // 更新界面显示
                    //string TagNames = DataConverHelper.ToIdNameString(listTagID);
                    txtRules.Text = Rules;

                    //System.Diagnostics.Debug.WriteLine($"接收到 {listTagID.Count} 个员工ID");
                }
                else
                {
                    // 如果没有选择员工，清空文本框
                    txtRules.Text = string.Empty;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("处理员工数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        /// <summary>
        /// 选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnCheck_Click(object sender, EventArgs e)
        {
            Form_CheckTag frm = new Form_CheckTag();

            // 订阅事件以接收员工数据
            frm.OnTagDataSelected += new TagDataTransferHandler(HandleTagDataReceived);

            // 如果textEdit2有值，解析并预选对应的员工
            if (!string.IsNullOrEmpty(txtRules.Text))
            {
                Dictionary<string, string> preSelectedEmps = listTagID;// ParseEmployeeText(txtRules.Text);
                if (preSelectedEmps.Count > 0)
                {
                    frm.SetPreSelectedTagloyees(preSelectedEmps);
                }
            }

            // 显示窗体
            frm.ShowDialog();
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnAdd_Click(object sender, EventArgs e)
        {
            // 防止重复点击
            btnAdd.Enabled = false;
            btnCancel.Enabled = false;

            // 记录操作开始时间，用于防止重复提交
            string requestId = Guid.NewGuid().ToString();

            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;

                // 检查必填字段是否有值
                string errorMessage = Check();
                if (!string.IsNullOrEmpty(errorMessage))
                {
                    MessageBox.Show(errorMessage, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                // 验证编码是否已被占用（并发检查）
                bool isCodeAvailable = await CheckCodeAvailability(txtLabelId.Text.Trim());
                if (!isCodeAvailable && UpdateType) // 只在新增模式下检查
                {
                    MessageBox.Show("标签编码已被占用，请刷新后重试", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                LableModel model = new LableModel();

                // 如果是修改模式，使用传入对象的ID和创建信息
                if (!UpdateType && CurrentLabel != null)
                {
                    model.LId = CurrentLabel.LId;
                    model.CreatedBy = CurrentLabel.CreatedBy;
                    model.CreatedTime = CurrentLabel.CreatedTime;
                    model.UpdatedTime = DateTime.Now;
                    model.LalId = CurrentLabel.LalId; // 保持原编码，防止修改
                }
                else
                {
                    // 新增模式，初始化创建信息
                    model.LId = 0;
                    model.CreatedTime = DateTime.Now;
                    model.CreatedBy = "00";
                    model.UpdatedTime = DateTime.Now;
                    model.LalId = txtLabelId.Text.Trim();
                }

                // 设置基本信息
                model.LabName = txtLabelName.Text.Trim();
                model.SupplierId = lookUpSupplier.EditValue?.ToString() ?? "";
                //model.SupplierName = lookUpSupplier.Text.Trim();
                model.Delimiter = txtDelimiter.Text.Trim();
                model.Memo = txtMemo.Text.Trim();
                model.IsEnable = toggleIsEnable.IsOn;

                // 设置规则格式
                // 将规则按照选择顺序生成字符串
                List<string> orderedRuleNames = new List<string>();
                List<string> orderedRuleIds = new List<string>();

                // 优先使用当前页面的规则选择顺序
                if (listTagID.Count > 0)
                {
                    foreach (KeyValuePair<string, string> id in listTagID)
                    {
                        orderedRuleIds.Add(id.Key);
                    }
                }

                string formatString = string.Join(",", orderedRuleIds);
                model.Format = formatString;

                // 将对象序列化为JSON
                string postData = JsonConvert.SerializeObject(model);

                // 添加请求ID，用于防止重复提交
                Dictionary<string, string> headers = new Dictionary<string, string>
                {
                    { "X-Request-ID", requestId },
                    { "X-Client-Timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") }
                };

                int maxRetries = 3;
                int retryCount = 0;
                bool success = false;

                while (!success && retryCount < maxRetries)
                {
                    try
                    {
                        // 根据操作类型选择API
                        string url = UpdateType ? "WareHouse/Label/AddLabel" : "WareHouse/Label/UpdatLabel";

                        // 使用带自定义头的请求方法
                        string json = await HttpClientHelper.RequestUrl(RequestType.Post, url, postData);
                        ApiResult<int> baseModel = JsonConvert.DeserializeObject<ApiResult<int>>(json);

                        if (baseModel.Code == ApiEnums.Success)
                        {
                            // 更新编码记录
                            await UpdateCode();

                            string message = UpdateType ? "添加成功" : "修改成功";
                            MessageBox.Show(message, "操作成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.DialogResult = DialogResult.OK;

                            // 标记成功
                            success = true;

                            // 关闭窗口
                            this.Close();
                        }
                        else
                        {
                            // 检查是否是因为并发冲突导致的失败
                            if (baseModel.Code == ApiEnums.Error)
                            {
                                retryCount++;
                                if (retryCount < maxRetries)
                                {
                                    // 等待一段时间后重试
                                    await Task.Delay(1000 * retryCount); // 逐次增加等待时间
                                    continue;
                                }
                            }

                            MessageBox.Show(baseModel.Message, "操作失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        retryCount++;
                        if (retryCount >= maxRetries)
                        {
                            MessageBox.Show("保存数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            break;
                        }

                        // 等待一段时间后重试
                        await Task.Delay(1000 * retryCount);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复按钮状态
                btnAdd.Enabled = true;
                btnCancel.Enabled = true;

                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 取消
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}